import { Injectable } from '@angular/core';
import {AppConfig, RabbitConfig} from '../../app.config';
import {Message} from '@stomp/stompjs';
import {Subscription} from 'rxjs/Subscription';
import {Observable} from 'rxjs/Observable';
import {StompService} from '@stomp/ng2-stompjs/index';

@Injectable()
export class MsgSubscribeService {
  private subscription: Subscription;
  public messages: Observable<Message>;
  public noAckMessages: Array<Message> = [];
  public subscribed: boolean;
  private headStomp: any;
  private subConstants: SubscribeConstants;
  constructor() {
    this.initObject();
  }
  /**
   * 实例化对象
   */
  initObject() {
    this.subConstants = new SubscribeConstants();
  }
  /**
   * 消息推送
   */
  public subscribe(rabbitConfig) {
    if (AppConfig.enableMsgSubscribe) {
      if (this.subscribed) {
        return;
      }
      if (!this.subscribed) {
        this.subscribed = true;
      }
      console.log('订阅消息推送');
      this.headStomp = new StompService(RabbitConfig);
      if (this.getDataType(rabbitConfig) === 'Object') {
        if (rabbitConfig.hasOwnProperty('isAck')) {
          this.subConstants.isAck = rabbitConfig.isAck
        }
        if (rabbitConfig.hasOwnProperty('isSingle')) {
          this.subConstants.isSingle = rabbitConfig.isSingle
        }
        if (rabbitConfig.hasOwnProperty('dataSubject')) {
          this.subConstants.dataSubject = rabbitConfig.dataSubject
        }
        if (rabbitConfig.hasOwnProperty('callback')) {
          this.subConstants.callback = rabbitConfig.callback
        }
        if (rabbitConfig.hasOwnProperty('url')) {
          this.subConstants.url = rabbitConfig.url
        }
      }
      const rabbitHeader = this.subConstants.isAck ? RabbitConfig.headers : RabbitConfig.noAckHeaders;
      this.messages = this.headStomp.subscribe(this.subConstants.url, rabbitHeader);
      this.subscription = this.messages.subscribe( (message: Message) => {
        if (this.subConstants.callback && typeof this.subConstants.callback === 'function') {
          this.subConstants.callback(message, this.headStomp)
        } else {
          this.onNext(message)
        }
      });
    }
  }
  public onNext = (message: Message) => {
    const mes = JSON.parse(message.body);
    if (this.subConstants.isAck) {
      mes.mesHeader = message.headers;
      mes.client = this.headStomp.client;
    }
    if (this.subConstants.dataSubject) {
      if (this.subConstants.isSingle) {
        this.subConstants.dataSubject.pushData(mes);
      } else {
        this.noAckMessages.unshift(mes);
        this.subConstants.dataSubject.pushData(this.noAckMessages)
      }
    }
  };
  public setAckMessage = ( header ) => {
    if (!!header) {
      this.headStomp.client.ack(header['message-id'], header.subscription, header);
    }
  };
  public unsubscribe() {
    if (AppConfig.enableMsgSubscribe) {
      if (!this.subscribed) {
        return;
      }
      console.log('取消消息推送');
      this.subscription.unsubscribe();
      this.subscription = null;
      this.messages = null;
      this.noAckMessages = null;
      this.subscribed = false;
      this.headStomp.disconnect();
    }
  }
  private  getDataType = (data) => {
    if (data instanceof Array) {
      return 'Array'
    } else if ( data instanceof Object ) {
      return 'Object';
    } else {
      return 'normal';
    }
  };
}

export class SubscribeConstants {
  url = '';  // rabbitMQ请求地址 todo（必填）
  callback: Function;  // 回调函数
  isSingle = true; // 是否存储之前接收的数据
  isAck = false; // 是否需要确认消息
  dataSubject; // 使用哪个订阅服务 todo（必填）若有回调函数存在则不需要定义，否则必须要定义
}
